﻿using Shop.Core.Helper;
using Shop.Core.Repository;
using Shop.Core.Share;
using Shop.IServices.Admin;
using Shop.Model.Dto.Admin.JurUser;
using Shop.Model.Entity.Jur;
using Shop.Model.View.Admin.JurUser;
using SqlSugar;

namespace Shop.Services.Admin;

public class JurUserService: IJurUserService
{
    private readonly RepositoryBase<JurUser> _userRepository;

    public JurUserService(RepositoryBase<JurUser> userRepository)
    {
        _userRepository = userRepository;
    }

    /// <summary>
    /// 添加用户
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    /// <exception cref="AppResult"></exception>
    public async Task<AppResult> AddUser(UserAddDto dto)
    {
        var exit = await _userRepository.AnyAsync(x => x.Account.Equals(dto.Account));
        if (exit)
            throw new Exception("账号已存在");

        _userRepository.BeginTran();
        var id = await _userRepository.InsertReturnBigIdentityAsync(new JurUser
        {
            Account = dto.Account,
            Name = dto.Name,
            PassWord = CommonHelper.Md5For32(dto.PassWord),
            CreateTime = DateTime.Now,
            Sex = dto.Sex,
            State = 0,
        });
        var db = _userRepository.Change<JurUserRole>();
        var list = dto.Roles.Select(x => new JurUserRole
        {
            RoleId = x,
            UserId = id,
        }).ToList();
        await db.InsertRangeAsync(list);
        _userRepository.CommitTran();
        return new AppResult();
    }

    /// <summary>
    /// 用户列表
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    /// <exception cref="NotImplementedException"></exception>
    public async Task<AppResult<PageModel<SysUserInforVo>>> GetUserList(SysUserPageSearchDto dto)
    {
        var count = await _userRepository.Queryable<JurUser>()
            .WhereIF(!string.IsNullOrWhiteSpace(dto.UserName), x => x.Name.Contains(dto.UserName))
            .WhereIF(!string.IsNullOrWhiteSpace(dto.Account), x => x.Account.Contains(dto.Account))
            .CountAsync();
        var data = _userRepository.Includes(x => x.UserRoles, r => r.Role)
            .WhereIF(!string.IsNullOrWhiteSpace(dto.UserName), x => x.Name.Contains(dto.UserName))
            .WhereIF(!string.IsNullOrWhiteSpace(dto.Account), x => x.Account.Contains(dto.Account))
            .Skip((dto.PageIndex - 1) * dto.PageSize)
            .Take(dto.PageSize)
            .OrderByDescending(x => x.CreateTime)
            .ToList(x => new SysUserInforVo
            {
                Id = x.Id,
                Account = x.Account,
                Name = x.Name,
                CreateTime = x.CreateTime,
                Sex = x.Sex,
                State = x.State,
                Roles = x.UserRoles.Select(y => new UserRoleVo { Id = y.Role.Id, Name = y.Role.Name }).ToList()
            });
        return new PageModel<SysUserInforVo>(dto, data, count);
    }

    /// <summary>
    /// 修改用户信息
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    /// <exception cref="AppResult"></exception>
    public async Task<AppResult> Update(UserModifyDto dto)
    {
        var user = await _userRepository.GetFirstAsync(x => x.Id == dto.Id);
        if (user == null)
            throw new Exception("找不到用户");
        user.Name = dto.Name;
        user.Sex = dto.Sex;
        user.State = dto.State;
        if (!string.IsNullOrWhiteSpace(dto.PassWord))
            user.PassWord = CommonHelper.Md5For32(dto.PassWord);
        List<JurUserRole> roles = new();
        foreach (var item in dto.Roles)
        {
            roles.Add(new JurUserRole { RoleId = item, UserId = user.Id });
        }
        _userRepository.BeginTran();
        var db = _userRepository.Change<JurUserRole>();
        await db.DeleteAsync(x => x.UserId == user.Id);
        await db.InsertRangeAsync(roles);
        await _userRepository.UpdateAsync(user);
        _userRepository.CommitTran();
        return new AppResult();
    }

    /// <summary>
    /// 修改密码
    /// </summary>
    /// <param name="uId"></param>
    /// <param name="inputValue"></param>
    /// <returns></returns>
    /// <exception cref="AppResult"></exception>
    public async Task<AppResult> ChangePassWord(long uId, string inputValue)
    {
        var user = await _userRepository.GetByIdAsync(uId);
        user.PassWord = CommonHelper.Md5For32(inputValue);
        await _userRepository.UpdateAsync(user);
        return new AppResult();
    }

    /// <summary>
    /// 获取用户的菜单权限列表
    /// </summary>
    /// <param name="uId"></param>
    /// <returns></returns>
    /// <exception cref="MenuListVo"></exception>
    public async Task<AppResult<List<MenuListVo>>> GetUserMenu(long uId)
        => await _userRepository.Queryable<JurUserRole, JurRole, JurRoleMenu, JurMenu>((ur, r, rm, m) => new object[] {
            JoinType.Inner,ur.RoleId == r.Id,
            JoinType.Inner,r.Id == rm.RoleId,
            JoinType.Inner,rm.MenuId == m.Id
        }).Where((ur, r, rm, m) => ur.UserId == uId && m.MenuType == 0)
        .Select((ur, r, rm, m) => new MenuListVo
        {
            Id = m.Id,
            MenuName = m.MenuName,
            Path = m.Path,
            CreateTime = m.CreateTime,
        }).Distinct()
        .ToListAsync();
}